package cn.flying.cloud.oauth.server.configuration.details;

import javax.annotation.Resource;

import java.util.HashSet;

import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.ClientRegistrationException;
import org.springframework.security.oauth2.provider.NoSuchClientException;
import org.springframework.security.oauth2.provider.client.BaseClientDetails;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import cn.flying.cloud.base.common.utils.Ft;
import cn.flying.cloud.oauth.entity.OauthClientDetail;
import cn.flying.cloud.oauth.service.OauthClientDetailService;


/**
 * 自定义数据库加载客户端信息
 *
 * @author: admin
 * @date: 2024年04月21日 23:05
 * @version: 1.0
 */
@Component
public class CustomClientDetailsService implements ClientDetailsService {

    @Resource
    private OauthClientDetailService oauthClientDetailService;

    /**
     * Load a client by the client id. This method must not return null.
     *
     * @param clientId The client id.
     * @return The client details (never null).
     * @throws ClientRegistrationException If the client account is locked, expired, disabled, or invalid for any other reason.
     */
    @Override
    public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {

        OauthClientDetail clientDetail = new OauthClientDetail();
        clientDetail.setClientId(clientId);
        clientDetail = oauthClientDetailService.detail(clientDetail);

        if (clientDetail == null) {
            throw new NoSuchClientException("No client with requested id: " + clientId);
        }

        BaseClientDetails clientDetails = new BaseClientDetails();
        clientDetails.setClientId(clientId);
        clientDetails.setClientSecret(clientDetail.getClientSecret());
        clientDetails.setResourceIds(Ft.String.isBlank(clientDetail.getResourceIds()) ? new HashSet<>() : StringUtils.commaDelimitedListToSet(clientDetail.getResourceIds()));
        clientDetails.setScope(Ft.String.isBlank(clientDetail.getScope()) ? new HashSet<>() : StringUtils.commaDelimitedListToSet(clientDetail.getScope()));
        clientDetails.setAuthorizedGrantTypes(Ft.String.isBlank(clientDetail.getAuthorizedGrantTypes()) ? new HashSet<>() : StringUtils.commaDelimitedListToSet(clientDetail.getAuthorizedGrantTypes()));
        clientDetails.setAuthorities(Ft.String.isBlank(clientDetail.getAuthorities()) ? new HashSet<>() : AuthorityUtils.commaSeparatedStringToAuthorityList(clientDetail.getAuthorities()));
        clientDetails.setRegisteredRedirectUri(Ft.String.isBlank(clientDetail.getWebServerRedirectUri()) ? new HashSet<>() : StringUtils.commaDelimitedListToSet(clientDetail.getWebServerRedirectUri()));
        clientDetails.setAccessTokenValiditySeconds(clientDetail.getAccessTokenValidity());
        clientDetails.setRefreshTokenValiditySeconds(clientDetail.getRefreshTokenValidity());

        return clientDetails;
    }
}
